1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 2e5 + 5; const int INF = 0x3f3f3f3f;
int n, m, cnt, ans[MAXN];
struct SegmentTree { int l, r, dat, lmax, rmax; } s[MAXN << 2]; void push_up(int p) { s[p].lmax = max((s[p << 1].lmax == s[p << 1].r - s[p << 1].l + 1) * s[p << 1 | 1].lmax + s[p << 1].lmax, s[p << 1].lmax); s[p].rmax = max((s[p << 1 | 1].rmax == s[p << 1 | 1].r - s[p << 1 | 1].l + 1) * s[p << 1].rmax + s[p << 1 | 1].rmax, s[p << 1 | 1].rmax); s[p].dat = max(max(s[p << 1].dat, s[p << 1 | 1].dat), s[p << 1].rmax + s[p << 1 | 1].lmax); } void build(int p, int l, int r) { s[p].l = l, s[p].r = r; if (l == r) { s[p].dat = s[p].lmax = s[p].rmax = 0; return; } int mid = (s[p].l + s[p].r) >> 1; build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r); push_up(p); } void update(int p, int x, int val) { if (s[p].l == s[p].r) { s[p].dat = s[p].lmax = s[p].rmax = val; return; } int mid = (s[p].l + s[p].r) >> 1; if (x <= mid) update(p << 1, x, val); if (x > mid) update(p << 1 | 1, x, val); push_up(p); } int query(int p, int l, int r) { if (s[p].l >= l && s[p].r <= r) return s[p].dat; int mid = (s[p].l + s[p].r) >> 1, lmax = 0, rmax = 0, addl = 0, addr = 0; if (l <= mid) { lmax = query(p << 1, l, r); if (r > mid) addl = min(mid - l + 1, s[p << 1].rmax); } if (r > mid) { rmax = query(p << 1 | 1, l, r); if (l <= mid) addr = min(r - mid, s[p << 1 | 1].lmax); } return max(addl + addr, max(lmax, rmax)); }
struct Question { int l, r, k, op, ind; } q[MAXN], q1[MAXN], q2[MAXN];
void solve(int vall, int valr, int optl, int optr) { if (optl > optr) return; if (vall == valr) { for (int i = optl; i <= optr; i++) if (q[i].op == 2) ans[q[i].ind] = vall; return; } int mid = (vall + valr) >> 1, cnt1 = 0, cnt2 = 0; for (int i = optl; i <= optr; i++) { if (q[i].op == 1) { if (q[i].l > mid) update(1, q[i].ind, 1), q2[++cnt2] = q[i]; else q1[++cnt1] = q[i]; } else { int tmp = query(1, q[i].l, q[i].r); if (tmp >= q[i].k) q2[++cnt2] = q[i]; else q1[++cnt1] = q[i]; } } for (int i = 1; i <= cnt1; i++) q[optl + i - 1] = q1[i]; for (int i = 1; i <= cnt2; i++) q[optl + cnt1 + i - 1] = q2[i]; solve(vall, mid, optl, optl + cnt1 - 1); for (int i = optl + cnt1; i <= optr; i++) if (q[i].op == 1) update(1, q[i].ind, 0); solve(mid + 1, valr, optl + cnt1, optr); }
int main() {
scanf("%d", &n); build(1, 1, n);
for (int i = 1, x; i <= n; i++) { scanf("%d", &x); q[++cnt] = Question{x, 1, 0, 1, i}; } scanf("%d", &m); for (int i = 1, l, r, k; i <= m; i++) { scanf("%d %d %d", &l, &r, &k); q[++cnt] = Question{l, r, k, 2, i}; } solve(-INF, INF, 1, cnt);
for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
return 0; }
|